package cn.epsilon3.utils;

import cn.hutool.log.Log;
import cn.hutool.log.LogFactory;
import com.alibaba.fastjson2.JSONObject;
import com.alipay.api.AlipayClient;
import com.alipay.api.AlipayConfig;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.request.AlipaySystemOauthTokenRequest;
import com.alipay.api.request.AlipayUserInfoShareRequest;
import com.alipay.api.response.AlipaySystemOauthTokenResponse;
import com.alipay.api.response.AlipayUserInfoShareResponse;
import cn.epsilon3.configBean.InitializingGithubConfig;
import cn.epsilon3.configBean.InitializingZfbConfig;
import cn.epsilon3.constant.CharacterConstant;
import cn.epsilon3.constant.HttpMethodEnum;
import cn.epsilon3.constant.UrlConstant;
import cn.epsilon3.domain.e3.dto.ThirdAuthLoginDTO;
import cn.epsilon3.domain.e3.vo.E3ThirdUserInfoShareVO;
import cn.epsilon3.exception.Epsilon3Exception;

import java.text.MessageFormat;
import java.util.HashMap;

/**
 * @description 三方SSO登录调用组件
 * @author: epsilon3
 * @date: 2023/10/25 14:59
 */

public class ThirdSSOUtils {

    private static final Log log = LogFactory.get();

    private static final String ALIPAY_FORMAT = "json";
    private static final String ALIPAY_SIGN_TYPE = "RSA2";
    private static final String ALIPAY_GRANT_TYPE = "authorization_code";
    private static final String ALIPAY_SCOPE_USER = "auth_user";
    private static final String ALIPAY_SCOPE_BASE = "auth_base";
    private static final String ALIPAY_USER_INFO_SHARE_RESPONSE = "alipay_user_info_share_response";

    /**
     * 支付宝登陆
     *
     * @param aliThirdAuthLoginDTO 回调信息
     * @return 支付宝会员信息
     */
    public static E3ThirdUserInfoShareVO toAlipay(ThirdAuthLoginDTO aliThirdAuthLoginDTO) {
        InitializingZfbConfig initializingZfbConfig = SpringContextUtils.getBean(InitializingZfbConfig.class);
        AlipaySystemOauthTokenResponse response;
        try {
            AlipayConfig alipayConfig = new AlipayConfig();
            alipayConfig.setServerUrl(UrlConstant.OPENAPI_ALIPAY);
            alipayConfig.setAppId(initializingZfbConfig.getAppId());
            alipayConfig.setPrivateKey(initializingZfbConfig.getPrivateKey());
            alipayConfig.setFormat(ALIPAY_FORMAT);
            alipayConfig.setAlipayPublicKey(initializingZfbConfig.getAlipayPublicKey());
            alipayConfig.setCharset(CharacterConstant.UTF8);
            alipayConfig.setSignType(ALIPAY_SIGN_TYPE);
            AlipayClient alipayClient = new DefaultAlipayClient(alipayConfig);
            AlipaySystemOauthTokenRequest request = new AlipaySystemOauthTokenRequest();
            request.setGrantType(ALIPAY_GRANT_TYPE);
            request.setCode(aliThirdAuthLoginDTO.getAuthCode());
            response = alipayClient.execute(request);
        } catch (Exception e) {
            throw new Epsilon3Exception("alipay.system.oauth.token error：" + e.getMessage());
        }
        response = AssertUtils.isNull(response, "alipay.system.oauth.token response null", log::error, "alipay.system.oauth.token: " + response.getBody());
        String accessToken = response.getAccessToken();
        AlipayClient alipayClient = new DefaultAlipayClient(UrlConstant.OPENAPI_ALIPAY,
                initializingZfbConfig.getAppId(),
                initializingZfbConfig.getPrivateKey(),
                ALIPAY_FORMAT,
                CharacterConstant.GBK,
                initializingZfbConfig.getAlipayPublicKey(),
                ALIPAY_SIGN_TYPE);
        AlipayUserInfoShareRequest request = new AlipayUserInfoShareRequest();
        AlipayUserInfoShareResponse userInfoResponse;
        try {
            userInfoResponse = alipayClient.execute(request, accessToken);
        } catch (Exception e) {
            throw new Epsilon3Exception("alipay.user.info.share error：" + e.getMessage());
        }
        userInfoResponse = AssertUtils.isNull(userInfoResponse, "alipay.user.info.share response null", log::error, "alipay.user.info.share: " + userInfoResponse.getBody());
        JSONObject jsonObject = JSONObject.parseObject(userInfoResponse.getBody()).getJSONObject(ALIPAY_USER_INFO_SHARE_RESPONSE);
        E3ThirdUserInfoShareVO aliUserInfoShareVO = new E3ThirdUserInfoShareVO();
        aliUserInfoShareVO.setOpenId(jsonObject.getString("open_id"));
        aliUserInfoShareVO.setAvatar(jsonObject.getString("avatar"));
        aliUserInfoShareVO.setNickName(jsonObject.getString("nick_name"));
        return AssertUtils.isNull(aliUserInfoShareVO, "alipay.system.oauth.token response null");
    }

    /**
     * github登陆
     *
     * @param githubThirdAuthLoginDTO github回调信息
     * @return github用户信息
     */
    public static E3ThirdUserInfoShareVO toGithub(ThirdAuthLoginDTO githubThirdAuthLoginDTO) {
        InitializingGithubConfig initializingGithubConfig = SpringContextUtils.getBean(InitializingGithubConfig.class);
        HashMap<String, String> headers = new HashMap<>(16);
        com.alibaba.fastjson.JSONObject body = new com.alibaba.fastjson.JSONObject();
        String accessUrl = MessageFormat.format(UrlConstant.GITHUB_TOKEN,
                initializingGithubConfig.getClientId(),
                initializingGithubConfig.getSecretId(),
                githubThirdAuthLoginDTO.getAuthCode());
        try {
            headers.put("accept", "application/json");
            com.alibaba.fastjson2.JSONObject accessTokenResult = HttpUtils.sendHttp(HttpMethodEnum.POST,
                    accessUrl,
                    headers,
                    body);
            String accessToken = (String) accessTokenResult.get("access_token");
            String token = AssertUtils.isBlank(accessToken, "github accessToken empty!");
            headers.put("Authorization", "Bearer " + token);
            com.alibaba.fastjson2.JSONObject githubUserMsgResult = HttpUtils.sendHttp(HttpMethodEnum.GET,
                    UrlConstant.GITHUB_USER_MSG,
                    headers,
                    body);
            JSONObject result = AssertUtils.isNull(githubUserMsgResult, "github response empty!");
            System.out.println(result);
            return null;
        } catch (Exception e) {
            throw new Epsilon3Exception("github_token error:" + e.getMessage());
        }
    }
}
